﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Graph
{
    public interface IGraph<T>
    {
        /// <summary>
        /// Adds the T to the graph
        /// </summary>
        /// <param name="T"></param>
        void Add(T vertex);

        /// <summary>
        /// Adds the supplied vertices to the graph
        /// </summary>
        /// <param name="vertices"></param>
        void Add(params T[] vertices);

        /// <summary>
        /// Finds a vertex equal to this one
        /// </summary>
        /// <param name="dummy"></param>
        T Find(T dummy);

        /// <summary>
        /// Removes the V and all connections from the graph
        /// </summary>
        /// <param name="V"></param>
        void Remove(T vertex);

        /// <summary>
        /// Creates a bidirectional edge between two nodes
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        void AddEdge(T from, T to);

        /// <summary>
        /// Connects the two Ves with an edge
        /// </summary>
        /// <param name="to"></param>
        /// <param name="from"></param>
        /// /// <param name="isBidirectional">Whether or not this connection is bidirectional</param>
        void AddEdge(T from, T to, bool isBidirectional);

        /// <summary>
        /// Connects two Ves with a weighted edge
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="isBidirectional"></param>
        /// <param name="weight"></param>
        void AddEdge(T from, T to, bool isBidirectional, int weight);

        /// <summary>
        /// Traverses the graph "depth-first" style and returns the vertices 
        /// in the order in which they were traversed
        /// </summary>
        /// <param name="start">The V to start from</param>
        /// <returns></returns>
        IList<T> DepthFirstTraversal(T start);

        /// <summary>
        /// 
        /// </summary>
        /// <param name="start"></param>
        /// <returns></returns>
        IList<T> BreadthFirstTraversal(T start);

        /// <summary>
        /// Removes connections between the specified vertices
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        void RemoveEdge(T from, T to);

        /// <summary>
        /// Returns an enumerable with all adjacent vertices relative to the supplied V
        /// </summary>
        /// <param name="V"></param>
        /// <returns></returns>
        ICollection<T> GetAdjacents(T vertex);

        /// <summary>
        /// Counts the vertices in the graph
        /// </summary>
        /// <returns></returns>
        int CountVertices();

        /// <summary>
        /// Checks if two vertices have an edge between them
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <returns></returns>
        bool HasEdge(T from, T to);

        /// <summary>
        /// Returns enumerator that contains all vertices in the graph
        /// </summary>
        /// <returns></returns>
        IEnumerator<T> Vertices();

        /// <summary>
        /// Checks if a vertex is in the graph.
        /// </summary>
        /// <param name="V"></param>
        /// <returns></returns>
        bool Contains(T vertex);
    }
}
